首先我們先來看看程式碼吧
var person = '小明';
var person2 = person;
person2 = '杰倫';
console.log(person, person2);
大家可以看看這樣 console.log(person, person2);
印出來的會是甚麼喔。
很明顯就是如預期的 小明 杰倫
, 感覺上就是先建立了 person
這個變數,並且賦值字串的'小明'給他,之後也建立了 person2
的變數,並且將 person
這個變數的內容指向給 person2
的變數。
這時候 person2
的變數 的值會是小明,之後再將 person2
的變數 重新賦值給一個字串'杰倫'。
所以最後印出來的結果會是 小明 杰倫
。很合理~
那我們再來看看另一段程式碼
var person = {
name: '小明'
};
var person2 = person;
person2.name = '杰倫';
console.log(person.name, person2.name);
console.log(person === person2);
這樣印出來的兩個 perosn 物件 裡面的 name 會是甚麼呢?
天啊~怎麼兩個都是 杰倫 !!! 怎麼會這樣呢?
而且用嚴格比對兩個物件居然還是 true ,代表完全相同ㄟ WHY?
其實這也是 Javascript 的特性喔!
Javascript 在賦予一個值在變數上的時候,會有兩個特性,一個稱為 傳值 另一個則是 傳參考。
左邊這些類型的資料型別就是傳值,也就是最上方字串的範例,做修改的時候只會更動被修改的變數內容。
而只要是物件型別的資料結構,就是屬於傳參考的模式,傳的參考其實是記憶體位置。
我們繼續往下看~
以上面字串的範例來看
當 var person2 = person;
的時候,就會變成下圖的狀況
接著我們改變了 person2
的內容,但因為是傳值,所以 person 並不會跟著改變。
接下來看一下 傳參考 的概念
為了方便起見呢 圖片中的 0x01 代表物件的內容被宣告的記憶體位置
可以看到當我們宣告 var person2 = person;
的時候,其實是將 person 的記憶體位置也指向給 person2,也就是 person 以及 person2都共享同一個記憶體空間的內容,也就是 0x01 的 物件內容。
所以依照這個邏輯來看,當我們改變了不論是 person 還是 person2 的 name,兩者取值印出來的結果都會一樣,是被改變後的結果。
那麼如果今天重新賦予 perosn2 新的 物件實字 的物件的話呢,他就會重新再另一個記憶體空間,放置被賦予的物件
這樣子更改 name 的值,就不會造成兩個一起更動的狀況嚕~
那我們直接看看程式碼~
var person = {
name: '小明'
};
var person2 = person;
person2 = {
name: '小明'
};
console.log(person.name, person2.name);
console.log(person === person2);
可以看到,我後來重新以一個 物件實字 的方式重新賦予給 person2 一個跟 person 一模一樣結構跟內容的物件。
但對於記憶體空間來說,這樣賦值的方式就會是指向另一個記憶體空間。
所以在嚴格比對的結果才會是false,從這點來看,關於 Javascript 物件類型的資料型別,以嚴格模式比對的時候,其實比對的是 記憶體位置 !!
這篇文章就先到這邊,下篇文章會有更完整的介紹
希望對大家的理解有幫助~汪汪